<script setup lang="ts">
import { appStore } from '@/stores/app'
const app = appStore()

import { ref, defineEmits, defineProps, onMounted } from 'vue'
import { i18n } from '@/i18n'
import * as log from 'loglevel'
import { array2json, json2array, notification } from '@/utils'
import { saveColumnset, sysparam } from '@/api'
import Draggable from 'vuedraggable'
import { type IField, type IParameter } from '@/contants'

const props = defineProps({
  name: {
    type: String,
    required: true
  },
  fields: {
    type: Array<IField>,
    required: true
  },
  unsave: {
    type: Boolean,
    required: false
  },
  advance: {
    type: Boolean,
    required: false
  }
})
const emits = defineEmits(['refresh'])
const data = ref({
  columns: new Array<IField>(),
  dialogVisible: false,
  drag: false,
  dragOptions: {
    animation: 200,
    group: 'description',
    disabled: false,
    ghostClass: 'ghost'
  }
})
//David: donot drag columns
// const columns = reactive<Array<IField>>([])

onMounted(() => {
  log.debug('ColumnSet Mounted ')
})

function setColumns() {
  log.debug(props.fields.values)
  sysparam(props.name).then((d: any) => {
    data.value.columns.splice(0)
    const allcolumns = json2array(d)
    props.fields.forEach((x: IField) => {
      let c = allcolumns.find((y: IField) => {
        return y.key == x.key
      })
      if (c) {
        c.selected = true
        c.width = x.width
        data.value.columns.push(c)
      }
    })
    allcolumns.forEach((x: IField) => {
      if (
        !props.fields.find((y: IField) => {
          return y.key == x.key
        })
      ) {
        x.selected = false
        data.value.columns.push(x)
      }
    })
    data.value.dialogVisible = true
  })
}

function submit() {
  const columns = data.value.columns
    .filter((x: IField) => {
      return x.selected
    })
    .map((x: IField) => {
      delete x.selected
      if (!x.width) {
        delete x.width
      }
      return x
    })
  log.debug(columns)
  emits('refresh', columns)
  data.value.dialogVisible = false
  if (!props.unsave) {
    const d = {
      sid: props.name,
      value: array2json(columns)
    } as IParameter
    saveColumnset(d)
      .then(() => {
        data.value.dialogVisible = false
        notification(i18n.global.t('parameter.' + props.name), i18n.global.t('message.saveok'))
      })
      .catch((e) => log.error(e))
  }
}
</script>

<template>
  <el-tooltip :content="$t('button.setColumn')" :disabled="app.disableTip">
    <el-button type="success" @click="setColumns" icon="Grid" size="small" />
  </el-tooltip>

  <el-dialog
    v-model="data.dialogVisible"
    :title="$t('dialog.columnset')"
    draggable
    append-to-body
    destroy-on-close
    :width="advance ? '400px' : '300px'"
  >
    <table class="colTable">
      <thead>
        <tr>
          <th width="70" style="text-align: center">
            {{ $t('label.selected') }}
          </th>
          <th width="200" style="text-align: left">
            {{ $t('label.fieldname') }}
          </th>
          <th v-if="advance" width="120" style="text-align: left">
            {{ $t('label.fieldwidth') }}
          </th>
        </tr>
      </thead>
      <Draggable
        v-model="data.columns"
        tag="tbody"
        item-key="label"
        class="list-group"
        :component-data="{
          tag: 'tr',
          type: 'tbody',
          name: !data.drag ? 'flip-list' : null
        }"
        v-bind="data.dragOptions"
        @start="data.drag = true"
        @end="data.drag = false"
      >
        <template #item="{ element }">
          <tr class="list-group-item">
            <td style="text-align: center">
              <el-checkbox
                v-model="element.selected"
                :disabled="element.key == 'operator'"
                size="large"
              />
            </td>
            <td>{{ $t('label.' + element.key) }}</td>
            <td v-if="advance">
              <el-input-number
                v-model="element.width"
                :min="20"
                :max="500"
                size="small"
                controls-position="right"
              />
            </td>
          </tr>
        </template>
      </Draggable>
    </table>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="data.dialogVisible = false">{{ $t('button.cancel') }}</el-button>
        <el-button type="primary" @click="submit">{{ $t('button.confirm') }}</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style>
.flip-list-move {
  transition: transform 0.5s;
}

.no-move {
  transition: transform 0s;
}

.ghost {
  opacity: 0.5;
  background: #c8ebfb;
}

.list-group-item {
  cursor: move;
}

.colTable tr:nth-child(even) {
  background: #f5f5f5;
}

.colTable thead {
  background: #f5f5f5;
  height: 50px;
}
</style>
